﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml;
using ZMenFM.Network.Spider;
using ZMenFM.Network.Song;

namespace ZMenFM.Network.Album
{
    public enum AlbumLoadStatus
    {
        ALS_LOADING,
        ALS_LOAD_OK,
        ALS_LOAD_FAILED
    }

    public class AlbumSongInfo      //专辑中每首歌的信息
    {
        public String Name;
        public String Artist;
        public String Extra;
    }

    public class AlbumItem
    {
        private XmlDocument AlbumXml = null;

        private String AlbumCoverUrl = "";      //专辑封面的地址
        private String AlbumXmlUrl = "";        //获取专辑XML的地址
        private String AlbumXmlStr = "";        //专辑XML的内容
        private String AlbumUrl = "";           //专辑的地址
        private String AlbumName = "";          //专辑名
        private String AlbumUser = "";          //专辑创建者
        private String AlbumID = "";            //专辑ID
        private String AlbumDescription = "";   //专辑信息描述
        private AlbumLoadStatus LoadStatus;
        private Thread LoadThread;

        private ZMSpider Spider = null;
        private Object Lockwho;                 //异步执行的媒介

        private List<SongItem> _SongList = new List<SongItem>();
        private List<AlbumSongInfo> _SongInfoList = new List<AlbumSongInfo>();

        private int CurrentIdx = -1;

        #region 构造函数
        /// <summary>
        /// 根据用户名、专辑编号获取信息
        /// </summary>
        /// <param name="albumID"></param>
        /// <param name="albumUser"></param>
        public AlbumItem(String albumID, String albumUser)
        {
            Lockwho = new object();
            LoadStatus = AlbumLoadStatus.ALS_LOADING;
            AlbumUser = albumUser;
            AlbumID = albumID;

            AlbumUrl = ZMConstUrl.baseUrl + ZMNetworkGlobal.UrlEncode(albumUser) + "/" + AlbumID + ".html";
            
            /** 开始分析专辑 */
            LoadThread = new Thread(new ThreadStart(_CommonConstruct));
            LoadThread.Start();
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id"></param>
        /// <param name="url"></param>
        /// <param name="cover"></param>
        /// <param name="name"></param>
        /// <param name="user"></param>
        /// <param name="desc"></param>
        public AlbumItem(string id, string url, string cover, string name, string user, string desc)
        {
            this.AlbumID = id;
            this.AlbumName = name;
            this.AlbumUrl = url;
            this.AlbumUser = user;
            this.AlbumCoverUrl = cover;
            this.AlbumDescription = desc;
        }

        /// <summary>
        /// 根据地址获取信息
        /// </summary>
        /// <param name="albumUrl"></param>
        public AlbumItem(String albumUrl)
        {
            Lockwho = new Object();
            LoadStatus = AlbumLoadStatus.ALS_LOADING;

            try
            {
                AlbumUrl = albumUrl;
                if (".html" == AlbumUrl.Substring(AlbumUrl.Length - 5, 5).ToLower())
                {
                    albumUrl = albumUrl.Substring(0, AlbumUrl.Length - 5);//去掉.html？这是为什么呢？
                }

                /** 寻找最后一个'/' */
                for (int i = albumUrl.Length - 1; i >= 0; i--)
                {
                    if (albumUrl[i] == '/')
                    {
                        AlbumID = albumUrl.Substring(i + 1);
                        albumUrl = albumUrl.Substring(0, i);
                        break;
                    }
                }

                /** 寻找最后一个'/' */
                for (int i = albumUrl.Length - 1; i >= 0; i--)
                {
                    if (albumUrl[i] == '/')
                    {
                        AlbumUser = albumUrl.Substring(i + 1);
                        AlbumUser = ZMNetworkGlobal.UrlDecode(AlbumUser);
                        break;
                    }
                }
            }
            catch (Exception)
            {
                LoadStatus = AlbumLoadStatus.ALS_LOAD_FAILED;
                return;
            }

            /** 开始分析专辑 */
            LoadThread = new Thread(new ThreadStart(_CommonConstruct));
            LoadThread.Start();
        }

        /// <summary>
        /// 公共构造函数
        /// </summary>
        private void _CommonConstruct()
        {
            AlbumXmlUrl = ZMConstUrl.albumXmlUrl + AlbumID + "&f=" + ZMNetworkGlobal.FromVar + "&.r=" + (new Random().NextDouble().ToString());

            Spider = new ZMSpider();
            Spider.InitContext(true, "$", false);

            /** 打开那张网页 */
            Spider.ClearGetData();
            Spider.ClearPostData();
            AlbumXmlStr = Spider.Get(AlbumXmlUrl, ZMSpiderCodec.VJCD_GB2312, ZMSpiderCookie.VJUCT_NO_COOKIE);

            /** 分析页面 - 页面错误 */
            //if (AlbumXmlStr.IndexOf(AlbumUser) == -1 || AlbumXmlStr.IndexOf(AlbumName) == -1)
            //{
            //    lock (Lockwho)
            //    {
            //        LoadStatus = AlbumLoadStatus.ALS_LOAD_FAILED;
            //    }
            //    return;
            //}

            /** 开始分析各项信息 */
            AlbumXml = new XmlDocument();
            try
            {
                AlbumXml.LoadXml(AlbumXmlStr);
                XmlElement root = (XmlElement)AlbumXml.FirstChild.NextSibling;
                AlbumUser = root.GetAttribute("author");
                AlbumName = root.GetAttribute("title");
                AlbumCoverUrl = root.GetAttribute("cover");

                /** 每首歌信息 */
                for (XmlElement node = (XmlElement)root.FirstChild; node != null; node = (XmlElement)node.NextSibling)
                {
                    /** 将歌曲载入 */
                    SongItem si = new SongItem(node.GetAttribute("n"), node.GetAttribute("a"), node.GetAttribute("e"));
                    _SongList.Add(si);
                    AlbumSongInfo asi = new AlbumSongInfo();
                    asi.Name = node.GetAttribute("n");
                    asi.Artist = node.GetAttribute("a");
                    asi.Extra = node.GetAttribute("e");

                    _SongInfoList.Add(asi);
                }
            }
            catch(Exception)
            {
                lock (Lockwho)
                {
                    LoadStatus = AlbumLoadStatus.ALS_LOAD_FAILED;
                }
                return;
            }

            lock (Lockwho)
            {
                LoadStatus = AlbumLoadStatus.ALS_LOAD_OK;
            }
        }
        #endregion

        public AlbumLoadStatus GetLoadStatus()
        {
            AlbumLoadStatus s;
            lock (Lockwho)
            {
                s = LoadStatus;
            }
            return s;
        }

        public override string ToString()
        {
            String str = "";
            str += ("专辑编号: " + AlbumID + "\n");
            str += ("专辑名: " + AlbumName + "\n");
            str += ("掌门人: " + AlbumUser + "\n");
            str += ("地址: " + AlbumUrl + "\n");
            str += ("数量: " + _SongInfoList.Count.ToString() + "\n");

            for (int i = 0; i < _SongInfoList.Count; i++)
            {
                //while (!_SongList[i]()) Thread.Sleep(10);
                if (_SongList[i].GetLoadStatus() == SongLoadStatus.SLS_NOT_START)
                {
                    _SongList[i].Load();
                }
                while (_SongList[i].GetLoadStatus() == SongLoadStatus.SLS_LOADING) Thread.Sleep(10);

                str += ("    [" + i.ToString() + "]: " + _SongList[i].ToString() + "\n");
            }

            return str;
        }

        public String GetAlbumName()
        {
            return AlbumName;
        }

        public String GetAlbumUser()
        {
            return AlbumUser;
        }

        public String GetAlbumCover()
        {
            return AlbumCoverUrl;
        }

        public string GetAlbumDescription()
        {
            return AlbumDescription;
        }

        //public List<SongItem> GetSongList()
        //{
        //    return _SongList;
        //}

        public List<SongItem> GetSongList()
        {
            return _SongList;
        }
        public List<AlbumSongInfo> GetSongInfoList()
        {
            return _SongInfoList;
        }
        public int Count { get { return _SongInfoList.Count; } }

        public SongItem FirstSong
        {
            get {
                if(Count == 0) return null;

                CurrentIdx = 0;
                return _SongList[CurrentIdx];
            }
        }

        public SongItem LastSong
        {
            get {
                if(Count == 0) return null;

                CurrentIdx = Count - 1;
                return _SongList[CurrentIdx];
            }
        }

        public SongItem this[int idx]
        {
            get {
                if(idx < 0) return null;
                if(idx >= Count) return null;

                CurrentIdx = idx;
                return _SongList[idx];
            }
        }
    }
}
